package com.pbd.server;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.sql.SQLException;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.StringTokenizer;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.servlet.ServletException;
//import javax.servlet.ServletException;
//import net.sf.gilead.core.hibernate.HibernateUtil;
//import net.sf.gilead.gwt.GwtConfigurationHelper;
//import net.sf.gilead.gwt.PersistentRemoteService;

import org.hibernate.Hibernate;
import org.hibernate.HibernateException;
import org.hibernate.Query;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.classic.Session;
import org.hibernate.engine.CascadeStyle;
import org.hibernate.impl.SessionFactoryImpl;
import org.hibernate.persister.collection.AbstractCollectionPersister;
import org.hibernate.persister.entity.AbstractEntityPersister;
import org.hibernate.persister.entity.EntityPersister;
import org.hibernate.stat.Statistics;
import org.hibernate.type.AssociationType;
import org.hibernate.type.CollectionType;
import org.hibernate.type.Type;

import com.google.gwt.user.client.rpc.IsSerializable;
import com.google.gwt.user.server.rpc.RemoteServiceServlet;
import com.pbd.client._HibernateService;
import com.pbd.client.dataassembler.DataClass;
import com.pbd.client.dataassembler.DataColumn;
import com.pbd.client.dataassembler.ReferenceDataColumn;

/**
 * @author cogent
 */
public class HibernateServiceImpl  extends RemoteServiceServlet implements _HibernateService, IsSerializable {

	private static final long serialVersionUID = 1111222233331131L;

	private static SessionFactory partySessionFactoryName;

	private Map classesMap;

	private Session openSession = null;

	// while run the application in development mode below state should be
	// false.
	public static final boolean WEB_MODE = false;
	public static final boolean DB_ORACLE = false;
	public static final boolean DB_MYSQL = true;

//	public void init() throws ServletException {
//		super.init();
//		HibernateUtil persistenceUtil = new HibernateUtil();
//		persistenceUtil.setSessionFactory(getSessionFactory());
//		PersistentBeanManager persistentBeanManager = GwtConfigurationHelper.initGwtStatelessBeanManager(persistenceUtil);
//		setBeanManager(persistentBeanManager);
//	
//		PersistentBeanManager beanManager = new PersistentBeanManager();
//		/*beanManager.setPersistenceUtil(persistenceUtil);
//		beanManager.setProxyStore(new StatelessProxyStore());
//		setBeanManager(beanManager);*/
//		ProxyClassMapper classMapper = new ProxyClassMapper();
//		
//		StatelessProxyStore proxyStore = new StatelessProxyStore();
//		proxyStore .setProxySerializer(new GwtProxySerialization());
//		beanManager.setProxyStore(proxyStore );
//		
//		classMapper.setPersistenceUtil(persistenceUtil);
//		beanManager.setClassMapper(classMapper);
//		beanManager.setPersistenceUtil(persistenceUtil);
//		setBeanManager(beanManager);
		
//	}

	public void updateObject(String dataObjectId, Long savedPKID, String[] propertiesExpression, String[] propertiesValues) {
		if (dataObjectId == null || savedPKID == null) {
			throw new IllegalArgumentException("You have passed the invalid data. Passed dataObjectId or pkid is null.");
		}
		String fullyQualifiedClassName = getFullyQualifiedClassName(dataObjectId);
		if (fullyQualifiedClassName == null)
			throw new RuntimeException("Class not found with named [" + dataObjectId + "]");
		int expSize = propertiesExpression == null ? 0 : propertiesExpression.length;
		int valSize = propertiesValues == null ? 0 : propertiesValues.length;
		if (expSize == 0) {
			throw new RuntimeException("[Passed expression size is zero]");
		}
		if (valSize == 0) {
			throw new RuntimeException("[Passed values size is zero]");
		}
		if (expSize != valSize)
			throw new RuntimeException("[Passed expression size and values size is not matched]");
		Session session = getSession();
		Transaction transaction = session.beginTransaction();
		try {
			Class objectClass = Class.forName(fullyQualifiedClassName);
			java.io.Serializable ins = (java.io.Serializable) session.get(objectClass, savedPKID);
			String[] methodsNames = new String[expSize];
			for (int i = 0; i < expSize; i++) {
				methodsNames[i] = "set" + propertiesExpression[i];
			}
			Method[] methods = objectClass.getDeclaredMethods();
			int length = (methods == null ? 0 : methods.length);
			int count = 0;
			for (int i = 0; i < length; i++) {
				String methoNameForInvoke = methods[i].getName();
				if (methoNameForInvoke.startsWith("get")) {
					continue;
				}
				Object param[] = new Object[1];
				for (int j = 0; j < methodsNames.length; j++) {
					if (methoNameForInvoke.equalsIgnoreCase(methodsNames[j])) {
						param[0] = propertiesValues[j];
						methods[i].invoke(ins, param);
						count++;
						break;
					}
				}
			}
			if (count == 0) {
				return;
			}
			session.update(ins);
			transaction.commit();
		} catch (Exception ex) {
			ex.printStackTrace();
			transaction.rollback();
			throw new RuntimeException("Exception while saving the data. [" + ex);
		} finally {
			if (session.isConnected())
				session.close();
		}
	}

	public void updateObject(String dataObjectId, Long savedPKID, Map<String, Object> dataValues, String whereClause) {
		System.err.println("----------------Inside of the Update Statement----------------");
		if (dataObjectId == null) {
			throw new IllegalArgumentException("You have passed the invalid data. Passed dataObjectId");
		}

		if (savedPKID == null && whereClause == null)
			throw new RuntimeException("WhereClause /Primary keyID  is required to update the [" + dataObjectId + "]");

		if (getFullyQualifiedClassName(dataObjectId) == null)
			throw new RuntimeException("Class not found with named [" + dataObjectId + "]");

		Transaction transaction = null;
		Session session = null;
		try {
			session = getSession();
			StringBuffer sbHSQL = new StringBuffer("Update " + dataObjectId + " set ");
			String primaryColumnName = getPrimaryColumnName(dataObjectId);
			for (Iterator queryIterator = dataValues.entrySet().iterator(); queryIterator.hasNext();) {
				Map.Entry entry = (Map.Entry) queryIterator.next();
				String key = (String) entry.getKey();
				if (key != null)
					sbHSQL.append(key + "=:" + key + ",");
			}

			if (sbHSQL.length() > 1)
				sbHSQL = new StringBuffer(sbHSQL.substring(0, sbHSQL.length() - 1));
			if (whereClause != null && whereClause.length() > 0)
				sbHSQL.append(" where " + whereClause);
			else
				sbHSQL.append(" where " + primaryColumnName + "=:" + primaryColumnName);
			transaction = session.beginTransaction();

			System.err.println(sbHSQL.toString());
			Query query = session.createQuery(sbHSQL.toString());

			for (Iterator valueIterator = dataValues.entrySet().iterator(); valueIterator.hasNext();) {
				Map.Entry entry = (Map.Entry) valueIterator.next();
				Object value = (Object) entry.getValue();
				if (value instanceof String)
					query.setString((String) entry.getKey(), (String) value);
				if (value instanceof Long)
					query.setLong((String) entry.getKey(), (Long) value);
				if (value instanceof Double)
					query.setDouble((String) entry.getKey(), (Double) value);
				if (value instanceof Date)
					query.setTimestamp((String) entry.getKey(), (Date) value);
				if (value instanceof BigDecimal)
					query.setBigDecimal((String) entry.getKey(), (BigDecimal) value);
				if (value instanceof Boolean)
					query.setBoolean((String) entry.getKey(), (Boolean) value);
				if (value instanceof Timestamp)
					query.setDate((String) entry.getKey(), new java.util.Date(((Timestamp) value).getTime()));
			}
			query.setLong(primaryColumnName, savedPKID);
			query.executeUpdate();
			transaction.commit();
		} catch (Exception ex) {
			ex.printStackTrace();
			transaction.rollback();
			throw new RuntimeException("Exception while saving the data. [" + ex);
		} finally {
			if (session.isConnected())
				session.close();
		}
	}

	public Integer updateObject(String dataObjectId, Map<String, Object> dataValues, String whereClause) {
		System.err.println("----------------Inside of the Update Statement----------------");
		if (dataObjectId == null) {
			throw new IllegalArgumentException("You have passed the invalid data. Passed dataObjectId");
		}

		int updatedRowCount = 0;

		if (getFullyQualifiedClassName(dataObjectId) == null)
			throw new RuntimeException("Class not found with named [" + dataObjectId + "]");

		Transaction transaction = null;
		Session session = null;
		try {
			session = getSession();
			StringBuffer sbHSQL = new StringBuffer("Update " + dataObjectId + " set ");
			String primaryColumnName = getPrimaryColumnName(dataObjectId);
			for (Iterator queryIterator = dataValues.entrySet().iterator(); queryIterator.hasNext();) {
				Map.Entry entry = (Map.Entry) queryIterator.next();
				String key = (String) entry.getKey();
				if (key != null)
					sbHSQL.append(key + "=:" + key + ",");
			}

			if (sbHSQL.length() > 1)
				sbHSQL = new StringBuffer(sbHSQL.substring(0, sbHSQL.length() - 1));
			if (whereClause != null && whereClause.length() > 0)
				sbHSQL.append(" where " + whereClause);
			else {
				if (primaryColumnName != null)
					sbHSQL.append(" where " + primaryColumnName + "=:" + primaryColumnName);
			}
			transaction = session.beginTransaction();
			System.err.println(sbHSQL.toString());
			Query query = session.createQuery(sbHSQL.toString());

			for (Iterator valueIterator = dataValues.entrySet().iterator(); valueIterator.hasNext();) {
				Map.Entry entry = (Map.Entry) valueIterator.next();
				Object value = (Object) entry.getValue();
				if (value instanceof String) {
					if (value != null && ((String) value).length() > 0)
						query.setString((String) entry.getKey(), (String) value);
					else {
						String columnName = (String) entry.getKey();
						query.setParameter(columnName, null, Hibernate.STRING);
					}
				}
				if (value instanceof Long) {
					if (value != null && (Long) value > 0)
						query.setLong((String) entry.getKey(), (Long) value);
					else {
						String columnName = (String) entry.getKey();
						query.setParameter(columnName, null, Hibernate.LONG);
					}
				}
				if (value instanceof Double)
					query.setDouble((String) entry.getKey(), (Double) value);
				if (value instanceof Date)
					query.setTimestamp((String) entry.getKey(), (Date) value);
				if (value instanceof BigDecimal)
					query.setBigDecimal((String) entry.getKey(), (BigDecimal) value);
				if (value instanceof Boolean)
					query.setBoolean((String) entry.getKey(), (Boolean) value);
				if (value instanceof Timestamp)
					query.setDate((String) entry.getKey(), new java.util.Date(((Timestamp) value).getTime()));
			}
			// query.setLong(primaryColumnName, savedPKID);
			updatedRowCount = query.executeUpdate();
			transaction.commit();
		} catch (Exception ex) {
			ex.printStackTrace();
			transaction.rollback();
			throw new RuntimeException("Exception while saving the data. [" + ex);
		} finally {
			if (session.isConnected())
				session.close();
		}
		return updatedRowCount;
	}

	public java.io.Serializable saveObject(java.io.Serializable obj) {
		if (obj == null)
			throw new IllegalArgumentException("You have passed the invalid data. Passed obj is null.");
		Session session = getSession();
		Transaction transaction = session.beginTransaction();
		try {
			System.out.println("try Catch Block");
			session.saveOrUpdate(obj);
			transaction.commit();
			return obj;
		} catch (Exception ex) {
			ex.printStackTrace();
			transaction.rollback();
			throw new RuntimeException("Exception while saving the data. [" + ex);
		} finally {
			if (session.isConnected())
				session.close();
		}
	}

	public List saveObjects(List objs) {
		int objsSize = objs == null ? 0 : objs.size();
		if (objsSize == 0)
			throw new IllegalArgumentException("You have passed the invalid data. Passed objList found null or empty.");
		Session session = getSession();
		Transaction transaction = session.beginTransaction();
		try {
			System.out.println("List try catch block");
			int size = objs == null ? 0 : objs.size();
			List dataObjects = new ArrayList(size);
			for (int i = 0; i < size; i++) {
				Object obj = objs.get(i);
				if (obj == null)
					throw new IllegalArgumentException("You have passed the invalid data. Passed obj is null.");
				if (obj instanceof java.io.Serializable) {
					session.saveOrUpdate(obj);
					dataObjects.add(obj);
				} else {
					throw new IllegalArgumentException("Passed object should be instance of Serializable or IsSerializable.");
				}
			}
			transaction.commit();
			return dataObjects;
		} catch (Exception ex) {
			transaction.rollback();
			ex.printStackTrace();
			throw new RuntimeException("Exception while saving the data. [" + ex);
		} finally {
			if (session.isConnected())
				session.close();
		}
	}

	public void deleteObject(java.io.Serializable obj) {
		Session session = getSession();
		Transaction transaction = session.beginTransaction();
		try {
			if (obj == null)
				return;
			session.delete(obj);
			transaction.commit();
		} catch (Exception ex) {
			ex.printStackTrace();
			transaction.rollback();
			throw new RuntimeException(ex);
		} finally {
			if (session.isConnected())
				session.close();
		}
	}

	
	public void deleteObjects(List objs) {
		int objsSize = (objs == null ? 0 : objs.size());
		if (objsSize == 0)
			return;
		Session session = getSession();
		Transaction transaction = session.beginTransaction();
		try {
			int size = (objs == null ? 0 : objs.size());
			for (int i = 0; i < size; i++) {
				Object obj = objs.get(i);
				if (obj == null)
					throw new IllegalArgumentException("You have passed the invalid data. Passed obj is null.");
				if (obj instanceof java.io.Serializable)
					session.delete(obj);
				else
					throw new RuntimeException("Passed object should be instance of Serializable.");
			}
			transaction.commit();
		} catch (Exception ex) {
			transaction.rollback();
			ex.printStackTrace();
			throw new RuntimeException(ex);
		} finally {
			if (session.isConnected())
				session.close();
		}
	}

	public java.io.Serializable findObjectByID(String dataObjectID, String id) {
		if (id == null || id.trim().length() == 0)
			throw new RuntimeException("Primary key value never be null or empty.");
		String primaryColumnName = getPrimaryColumnName(dataObjectID);
		if (primaryColumnName == null || primaryColumnName.trim().length() == 0)
			throw new RuntimeException("Primary key column never be null or empty.");
		String queryStr = "from " + dataObjectID + " " + dataObjectID + " where " + dataObjectID + "." + primaryColumnName + "=:id";
		Session session = getSession();
		try {
			Query query = session.createQuery(queryStr);
			query.setString("id", id);
			return (java.io.Serializable) query.uniqueResult();
		} catch (Exception ex) {
			throw new RuntimeException("Excepton while fetching the data for passed database query [" + queryStr + "]." + ex);
		} finally {
			if (session.isConnected())
				session.close();
		}
	}

	public java.io.Serializable findObjectByID(String dataObjectID, Number id) {
		if (id == null)
			throw new RuntimeException("Primary key value never be null.");
		return findObjectByID(dataObjectID, id.toString());
	}

	// Below Function is returning the column name based on the metadata of the
	// class
	public String getPrimaryColumnName(String dataObjectID) {
		String clazzName = getFullyQualifiedClassName(dataObjectID);
		AbstractEntityPersister entityPersister = getAbstractEntityPersister(clazzName);
		String identifierPropertyName = entityPersister.getIdentifierPropertyName();
		return identifierPropertyName;
	}

	public String getCascadeValue(String dataObjectID, String propertyName) {
		String clazzName = getFullyQualifiedClassName(dataObjectID);
		AbstractEntityPersister entityPersister = getAbstractEntityPersister(clazzName);
		String[] propertyNames = entityPersister.getPropertyNames();
		int propertyNamesLength = propertyNames == null ? 0 : propertyNames.length;
		int propertyIndex = -1;
		for (int i = 0; i < propertyNamesLength; i++) {
			String propertyNameVal = propertyNames[i];
			if (propertyNameVal.equalsIgnoreCase(propertyName)) {
				propertyIndex = i;
				break;
			}
		}
		if (propertyIndex >= 0) {
			CascadeStyle[] cascadeStyles = entityPersister.getPropertyCascadeStyles();
			CascadeStyle cascadeStyle = cascadeStyles[propertyIndex];
			if (cascadeStyle != null) {
				String cascadeStyleStr = cascadeStyle.toString();
				if (cascadeStyleStr.indexOf("_") != -1) {
					cascadeStyleStr = cascadeStyleStr.substring(cascadeStyleStr.indexOf("_") + 1);
					if (cascadeStyleStr.indexOf("]") != -1)
						cascadeStyleStr = cascadeStyleStr.substring(0, cascadeStyleStr.lastIndexOf("]"));
				}
				return cascadeStyleStr;
			}
		}
		return null;
	}

	private AbstractEntityPersister getAbstractEntityPersister(String clazzName) {
		SessionFactory sessionFactory = getSessionFactory();
		return (AbstractEntityPersister) sessionFactory.getClassMetadata(clazzName);
	}

	// getting the primary key object name from the
	// sessionFactory.getAllclassmetadata

	public String getFullyQualifiedClassName(String dataObjectId) {
		if (dataObjectId == null || dataObjectId.trim().length() == 0)
			throw new RuntimeException("DataObjectId never be null or empty.");
		if (dataObjectId.indexOf(".") != -1)
			return dataObjectId;
		SessionFactory sessionFactory = getSessionFactory();
		java.util.Map classMetaDataMaps = sessionFactory.getAllClassMetadata();
		Set classNamesSet = classMetaDataMaps.keySet();
		Iterator iter = classNamesSet.iterator();
		while (iter.hasNext()) {
			String className = (String) iter.next();
			if (className != null && className.trim().length() > 0) {
				String chkingClassName = (className.indexOf(".") != -1) ? className.substring(className.lastIndexOf(".") + 1) : className;
				if (chkingClassName.equals(dataObjectId))
					return className;
			}
		}
		return null;
	}

	public String findValue(String calculatedFormulaExpression) {
		return findValue(calculatedFormulaExpression, false);
	}

	public String findValue(String calculatedFormulaExpression, boolean eatException) {
		if (calculatedFormulaExpression != null && calculatedFormulaExpression.trim().length() > 0) {
			try {
				Query query = getSession().createSQLQuery("select " + calculatedFormulaExpression + " from Dual ");
				List list = query.list();
				int size = list == null ? 0 : list.size();
				for (int i = 0; i < size; i++) {
					Object dataObject = list.get(i);
					if (dataObject != null)
						return dataObject.toString();
				}
			} catch (Exception ex) {
				if (!eatException)
					throw new RuntimeException(ex);
				else
					return null;
			}
		}
		return null;
	}
	public java.io.Serializable saveObject(java.io.Serializable obj, Boolean endorsement) {
		if (obj == null)
			throw new IllegalArgumentException("You have passed the invalid data. Passed obj is null.");
		
		Session session = getSession();
		Transaction transaction = session.beginTransaction();
		try {
			session.saveOrUpdate(obj);
			transaction.commit();
			return obj;
		} catch (Exception ex) {
			ex.printStackTrace();
			transaction.rollback();
			throw new RuntimeException("Exception while saving the data. [" + ex);
		} finally {
			if (session.isConnected())
				session.close();
		}
	}

	public Long findValue(String functionName, String dataObjectId, String columnName, String filterString) {
		if (functionName == null || functionName.trim().length() == 0)
			throw new IllegalArgumentException("Passed functionName is invalid. FunctionName never be null or empty.");
		String fullyQualifiedClassName = getFullyQualifiedClassName(dataObjectId);
		if (fullyQualifiedClassName == null)
			throw new IllegalArgumentException("Passed data is invalid. BDO class is not exists corresponnding to [" + dataObjectId + "]");
		Session session = getSession();
		try {
			if (fullyQualifiedClassName.indexOf(".") != -1)
				fullyQualifiedClassName = fullyQualifiedClassName.substring((fullyQualifiedClassName.lastIndexOf(".") + 1));
			if (columnName == null)
				columnName = "*";
			String filter = "";
			if (filterString != null && filterString.trim().length() > 0)
				filter = " WHERE " + filterString;
			Query query = session.createQuery("select " + functionName + " (" + columnName + ") from " + fullyQualifiedClassName + " " + fullyQualifiedClassName + filter);
			List list = query.list();
			int size = (list == null ? 0 : list.size());
			if (size > 0)
				return (Long) list.get(0);
			return null;
		} catch (Exception ex) {
			ex.printStackTrace();
			throw new RuntimeException("Exception while executing query " + ex);
		} finally {
			if (session.isConnected())
				session.close();
		}
	}

	public List findObjects(String dataObjectId, String filterStr) {
		return findObjects(dataObjectId, filterStr, (String) null);
	}

	public List findObjects(String dataObjectId, String filterStr, String orderBy) {
		return findObjects(dataObjectId, filterStr, orderBy, false);
	}

	public List findObjects(String dataObjectId, String filterStr, String orderBy, boolean fromServerSide) {
		return getSearchingDataResult(dataObjectId, null, filterStr, null, orderBy, false, fromServerSide, false);
	}

	public List findObjects(String dataObjectId, String filterStr, String[] filterAndOrderExtraColumnExps) {
		return findObjects(dataObjectId, filterStr, null, filterAndOrderExtraColumnExps);
	}

	public List findObjects(String dataObjectId, String filterStr, String orderBy, String[] filterAndOrderExtraColumnExps) {
		return findObjects(dataObjectId, filterStr, orderBy, filterAndOrderExtraColumnExps, false);
	}

	public List findObjects(String dataObjectId, String filterStr, String orderBy, String[] filterAndOrderExtraColumnExps, boolean fromServerSide) {
		return populateDatas(dataObjectId, null, filterStr, orderBy, filterAndOrderExtraColumnExps, false, fromServerSide);
	}

	public List findObjectsOnObjectBasis(String dataObjectId, String[] columnExpressions, String filterStr, String[] filterAndOrderExtraColumnExps) {
		return findObjectsOnObjectBasis(dataObjectId, columnExpressions, filterStr, null, filterAndOrderExtraColumnExps);
	}

	public List findObjectsOnObjectBasis(String dataObjectId, String[] columnExpressions, String filterStr, String orderBY, String[] filterAndOrderExtraColumnExps) {
		return populateDatas(dataObjectId, columnExpressions, filterStr, orderBY, filterAndOrderExtraColumnExps, false);
	}

	public List findObjectsOnObjectBasis(String dataObjectId, String[] columnExpressions, String filterStr, String[] filterAndOrderExtraColumnExps, boolean fromServerSide) {
		return populateDatas(dataObjectId, columnExpressions, filterStr, null, filterAndOrderExtraColumnExps, fromServerSide);
	}

	public List findObjectsOnObjectBasis(String dataObjectId, String filterStr, String[] filterAndOrderExtraColumnExps) {
		return findObjectsOnObjectBasis(dataObjectId, null, filterStr, filterAndOrderExtraColumnExps);
	}

	private List populateDatas(String dataObjectId, String[] columnExpressions, String filterStr, String orderBy, String[] filterAndOrderExtraColumnExps, boolean fromServerSide) {
		String fullyQualifiedClassName = getFullyQualifiedClassName(dataObjectId);
		if (fullyQualifiedClassName == null)
			throw new RuntimeException("Class not found with named [" + dataObjectId + "]");
		String[] populatedJoinAndDisplayColumnExp = getPopulatedJoinsStatements(dataObjectId, fullyQualifiedClassName, columnExpressions, filterAndOrderExtraColumnExps);
		if (populatedJoinAndDisplayColumnExp != null && populatedJoinAndDisplayColumnExp.length == 2) {
			return getSearchingDataResult(fullyQualifiedClassName, columnExpressions, filterStr, orderBy, populatedJoinAndDisplayColumnExp[1], fromServerSide, false);
		}
		return null;
	}

	private String[] getPopulatedJoinsStatements(String dataObjectID, String fullyQualifiedClassName, String[] columnExpressions, String[] filterAndOrderExtraColumnExps) {
		String joinStr = "";
		Map chainedColumnExpressionMap = null;
		Map aliasesClassNameMap = null;
		Set associatedAliases = new HashSet();
		Class clazz = getDataObjectIdClass(fullyQualifiedClassName);
		int filterAndOrderExtraColumnExpsLength = (filterAndOrderExtraColumnExps == null ? 0 : filterAndOrderExtraColumnExps.length);
		if (filterAndOrderExtraColumnExpsLength > 0) {
			for (int i = 0; i < filterAndOrderExtraColumnExpsLength; i++) {
				String filterAndOrderExtraColumnExp = filterAndOrderExtraColumnExps[i];
				if (filterAndOrderExtraColumnExp.indexOf(".") == -1) {
					boolean validColumnExpressions = validColumnExpression(clazz, filterAndOrderExtraColumnExp);
					if (!validColumnExpressions)
						throw new RuntimeException("Passed columnExpression is not valid. ColumnExpression [" + filterAndOrderExtraColumnExp + "] is not exists in Class [" + clazz.getName() + "]");
				} else {
					if (chainedColumnExpressionMap == null)
						chainedColumnExpressionMap = new HashMap();
					if (aliasesClassNameMap == null)
						aliasesClassNameMap = new HashMap();
					getPopulatedQueryStr(filterAndOrderExtraColumnExp, clazz, dataObjectID, chainedColumnExpressionMap, aliasesClassNameMap, associatedAliases);
					List colJoinerDataList = (List) chainedColumnExpressionMap.get(filterAndOrderExtraColumnExp);
					joinStr += ((String) colJoinerDataList.get(1) + " ");
				}
			}
		}
		return new String[] { "", joinStr };
	}

	private String getPopulatedQueryStr(String columnExpression, Class clazz, String parentAliasName, Map dataPopulatedMap, Map aliasesClassNameMap, Set associatedAliases) {
		AbstractEntityPersister entityPersister = getAbstractEntityPersister(clazz.getName());
		String[] columnExpressions = getColumnExpressions(columnExpression, ".");
		int columnExpressionsLength = (columnExpressions == null ? 0 : columnExpressions.length);
		String comparingStr = columnExpression;
		String associatedJoin = "";
		String displayColumnExpression = null;
		String populatedColExpression = null;
		if (dataPopulatedMap.size() > 0) {
			while (comparingStr.indexOf(".") != -1) {
				comparingStr = (comparingStr.substring(0, comparingStr.lastIndexOf(".")));
				List dataPopulatedList = (List) dataPopulatedMap.get(comparingStr);
				if (dataPopulatedList != null) {
					populatedColExpression = comparingStr;
					parentAliasName = (String) dataPopulatedList.get(0);
					clazz = (Class) dataPopulatedList.get(2);
					entityPersister = getAbstractEntityPersister(clazz.getName());
					String colExpression = null;
					if (columnExpression.indexOf(".") != -1) {
						colExpression = columnExpression.substring(0, columnExpression.lastIndexOf("."));
						String tempColExpression = columnExpression.substring(columnExpression.lastIndexOf("."));
						colExpression = colExpression.replaceAll(comparingStr, "");
						columnExpression = colExpression + tempColExpression;
					} else {
						columnExpression = columnExpression.replaceAll(comparingStr, "");
					}
					columnExpression = columnExpression.substring(1);
					columnExpressions = getColumnExpressions(columnExpression, ".");
					columnExpressionsLength = columnExpressions == null ? 0 : columnExpressions.length;
					break;
				}
			}
		}
		String associatedClazzNameAlias = null;
		for (int i = 0; i < columnExpressionsLength; i++) {
			String colExpression = columnExpressions[i];
			List dataPopulatedList = new ArrayList();
			if (populatedColExpression == null)
				populatedColExpression = colExpression;
			else
				populatedColExpression = populatedColExpression + "." + colExpression;
			boolean validColumnExpressions = validColumnExpression(clazz, colExpression);
			if (!validColumnExpressions)
				throw new RuntimeException("Passed column is not valid. Passed columnExpression [" + colExpression + "] is not found in class [" + entityPersister.getEntityName() + "]");
			String[] propertyNames = entityPersister.getPropertyNames();
			int propertyNamesLength = propertyNames == null ? 0 : propertyNames.length;
			boolean colExpressionnPopulate = false;
			for (int j = 0; j < propertyNamesLength; j++) {
				String propertyName = propertyNames[j];
				if (propertyName.equals(colExpression)) {
					colExpressionnPopulate = true;
					Type propertyType = entityPersister.getPropertyType(colExpression);
					if (!isPrimitive(propertyType.getReturnedClass()) || !isDate(propertyType.getReturnedClass())) {
						// String[] propertyColumnNames =
						// entityPersister.getPropertyColumnNames(propertyName);
						if (propertyType instanceof CollectionType) {
							CollectionType collectionType = (CollectionType) propertyType;
							AbstractCollectionPersister collectionPersister = (AbstractCollectionPersister) ((SessionFactoryImpl) getSessionFactory()).getCollectionPersister(collectionType.getRole());
							entityPersister = (AbstractEntityPersister) collectionPersister.getElementPersister();
							String fullyQualifiedAssociatedClazzName = entityPersister.getEntityName();
							try {
								clazz = Class.forName(fullyQualifiedAssociatedClazzName);
							} catch (ClassNotFoundException e) {
								throw new RuntimeException("Class not found with named [" + fullyQualifiedAssociatedClazzName + "]");
							}
							String[] associatedClassNames = getColumnExpressions(fullyQualifiedAssociatedClazzName, ".");
							String associatedClazzName = associatedClassNames[associatedClassNames.length - 1];
							associatedClazzNameAlias = associatedClazzName;
							if (associatedAliases.contains(associatedClazzNameAlias))
								associatedClazzNameAlias = associatedClazzNameAlias + propertyName;

							associatedJoin = associatedJoin + (" left join " + parentAliasName + "." + propertyName + " " + associatedClazzNameAlias);
							parentAliasName = associatedClazzName;
							if (associatedAliases.contains(parentAliasName))
								parentAliasName = parentAliasName + propertyName;
						} else if (propertyType instanceof AssociationType) {
							clazz = propertyType.getReturnedClass();
							String associatedClassName = clazz.getName();
							entityPersister = getAbstractEntityPersister(associatedClassName);
							String[] associatedClassNames = getColumnExpressions(associatedClassName, ".");
							String associatedDataObjectId = associatedClassNames[associatedClassNames.length - 1];
							associatedClazzNameAlias = associatedDataObjectId;
							if (associatedAliases.contains(associatedClazzNameAlias))
								associatedClazzNameAlias = associatedClazzNameAlias + propertyName;
							associatedJoin = associatedJoin + (" left join " + parentAliasName + "." + propertyName + " " + associatedClazzNameAlias);
							parentAliasName = associatedDataObjectId;
							if (associatedAliases.contains(parentAliasName))
								parentAliasName = parentAliasName + propertyName;
						} else
							throw new UnsupportedOperationException("Simple property are not supported.");
						aliasesClassNameMap.put(associatedClazzNameAlias, clazz);
						associatedAliases.add(parentAliasName);
						dataPopulatedList.add(0, associatedClazzNameAlias);
						dataPopulatedList.add(1, associatedJoin);
						dataPopulatedList.add(2, clazz);
					}
					dataPopulatedMap.put(populatedColExpression, dataPopulatedList);
					break;
				}
			}
			if (!colExpressionnPopulate) {
				String identifierPropertyName = entityPersister.getIdentifierPropertyName();
				if (colExpression.equals(identifierPropertyName)) {
					aliasesClassNameMap.put(associatedClazzNameAlias, clazz);
					dataPopulatedList.add(0, associatedClazzNameAlias);
					dataPopulatedList.add(1, associatedJoin);
					dataPopulatedList.add(2, clazz);
					dataPopulatedMap.put(populatedColExpression, dataPopulatedList);
					displayColumnExpression = parentAliasName + "." + colExpression;
				}
			}
		}
		return displayColumnExpression;
	}

	public List findObjects(String dataObjectId, String[] columnExpressions, String filterStr) {
		return findObjects(dataObjectId, columnExpressions, filterStr, (String) null);
	}

	public List findObjects(String dataObjectId, String[] columnExpressions, String filterStr, boolean useNativeSQL) {
		return findObjects(dataObjectId, columnExpressions, filterStr, (String) null, useNativeSQL);
	}

	public List findObjects(String dataObjectId, String[] columnExpressions, String filterStr,String orderBy, boolean useNativeSQL,boolean allRecords) {
		return findObjects(dataObjectId, columnExpressions, filterStr, orderBy, useNativeSQL,false,allRecords);
	}
	
	public List findObjects(String dataObjectId, String[] columnExpressions, String filterStr, String orderBy, boolean useNativeSQL) {
		return findObjects(dataObjectId, columnExpressions, filterStr, orderBy, useNativeSQL, false,false);
	}

	private List findObjects(String dataObjectId, String[] columnExpressions, String filterStr, String orderBy, boolean useNativeSQL, boolean fromServerSide,boolean allRecords) {
		return populateDatas(dataObjectId, columnExpressions, filterStr, orderBy, null, useNativeSQL, fromServerSide,allRecords);
	}

	private List populateDatas(String dataObjectId, String[] columnExpressions, String filterStr, String orderBy, String[] filterAndOrderExtraColumnExps, boolean useNativeSQL, boolean fromServerSide, boolean allRecord) {
		String fullyQualifiedClassName = getFullyQualifiedClassName(dataObjectId);
		if (fullyQualifiedClassName == null)
			throw new RuntimeException("Class not found with named [" + dataObjectId + "]");
		String[] populatedJoinAndDisplayColumnExp = getPopulatedJoinsStatements(dataObjectId, fullyQualifiedClassName, columnExpressions, filterAndOrderExtraColumnExps, useNativeSQL);
		if (populatedJoinAndDisplayColumnExp != null && populatedJoinAndDisplayColumnExp.length == 2) {
			String colExpressionStr = populatedJoinAndDisplayColumnExp[0];
			String joinStr = populatedJoinAndDisplayColumnExp[1];
			colExpressionStr = ((colExpressionStr.trim().length() > 0) && (colExpressionStr.indexOf(",") != -1)) ? colExpressionStr.substring(0, colExpressionStr.lastIndexOf(",")) : colExpressionStr;
			return getSearchingDataResult(fullyQualifiedClassName, colExpressionStr, filterStr, joinStr, orderBy, useNativeSQL, fromServerSide, allRecord);
		}
		return null;
	}

	private List populateDatas(String dataObjectId, String[] columnExpressions, String filterStr, String orderBy, String[] filterAndOrderExtraColumnExps, boolean useNativeSQL, boolean fromServerSide) {
		return populateDatas(dataObjectId, columnExpressions, filterStr, orderBy, filterAndOrderExtraColumnExps, useNativeSQL, fromServerSide, false);
	}

	public List findObjects(String dataObjectId, String[] columnExpressions, String filterStr, String orderBy) {
		return populateDatas(dataObjectId, columnExpressions, filterStr, orderBy, null, false, false);
	}

	public List findObjects(String dataObjectId, String[] columnExpressions, String filterStr, String[] filterAndOrderExtraColumnExps, boolean useNativeSQL) {
		return findObjects(dataObjectId, columnExpressions, filterStr, null, filterAndOrderExtraColumnExps);
	}

	public List findObjects(String dataObjectId, String[] columnExpressions, String filterStr, String[] filterAndOrderExtraColumnExps) {
		return findObjects(dataObjectId, columnExpressions, filterStr, filterAndOrderExtraColumnExps, false);
	}

	public List findObjects(String dataObjectId, String[] columnExpressions, String filterStr, String orderBy, String[] filterAndOrderExtraColumnExps, boolean useNativeSQL) {
		return findObjects(dataObjectId, columnExpressions, filterStr, orderBy, filterAndOrderExtraColumnExps, useNativeSQL, false);
	}

	public List findObjects(String dataObjectId, String[] columnExpressions, String filterStr, String orderBy, String[] filterAndOrderExtraColumnExps, boolean useNativeSQL, boolean fromServerSide) {
		return populateDatas(dataObjectId, columnExpressions, filterStr, orderBy, filterAndOrderExtraColumnExps, useNativeSQL, fromServerSide);
	}

	public List findObjects(String dataObjectId, String[] columnExpressions, String filterStr, String orderBy, String[] filterAndOrderExtraColumnExps) {
		return findObjects(dataObjectId, columnExpressions, filterStr, orderBy, filterAndOrderExtraColumnExps, false);
	}

	private boolean isColumnFromAssociatedClass(String[] columnExpressions) {
		int columnExpressionsLength = columnExpressions == null ? 0 : columnExpressions.length;
		for (int i = 0; i < columnExpressionsLength; i++) {
			String columnExpression = columnExpressions[i];
			if (columnExpression.indexOf(".") != -1)
				return true;
		}
		return false;
	}

	private String[] getPopulatedJoinsStatements(String dataObjectID, String fullyQualifiedClassName, String[] columnExpressions, String[] filterAndOrderExtraColumnExps, boolean useNativeSql) {
		String colExpressionStr = "";
		String joinStr = "";
		Map chainedColumnExpressionMap = null;
		Map aliasesClassNameMap = null;
		Set associatedAliases = new HashSet();
		associatedAliases.add(dataObjectID);
		Class clazz = getDataObjectIdClass(fullyQualifiedClassName);
		int columnExpressionsLength = columnExpressions == null ? 0 : columnExpressions.length;
		if (columnExpressionsLength > 0) {
			boolean populateColumnExpression = isColumnFromAssociatedClass(columnExpressions);
			for (int i = 0; i < columnExpressionsLength; i++) {
				String columnExpression = columnExpressions[i];
				if (columnExpression.indexOf(".") == -1) {
					boolean validColumnExpressions = validColumnExpression(clazz, columnExpression);
					if (!validColumnExpressions)
						throw new RuntimeException("Passed columnExpression is not valid. ColumnExpression [" + columnExpression + "] is not exists in Class [" + clazz.getName() + "]");
					if (columnExpression != null && columnExpression.trim().length() > 0) {
						if (populateColumnExpression) {
							if (useNativeSql)
								colExpressionStr += (dataObjectID + "." + columnExpression + " as col" + i) + ", ";
							else
								colExpressionStr += (dataObjectID + "." + columnExpression) + ", ";
						} else
							colExpressionStr += columnExpression + ", ";
					}
				} else {
					if (chainedColumnExpressionMap == null)
						chainedColumnExpressionMap = new HashMap();
					if (aliasesClassNameMap == null)
						aliasesClassNameMap = new HashMap();
					String queryData = getPopulatedQueryStr(columnExpression, clazz, dataObjectID, chainedColumnExpressionMap, aliasesClassNameMap, associatedAliases, useNativeSql);
					if (useNativeSql)
						colExpressionStr += (queryData + " as col" + i) + ", ";
					else
						colExpressionStr += (queryData + ", ");
					List colJoinerDataList = (List) chainedColumnExpressionMap.get(columnExpression);
					joinStr += ((String) colJoinerDataList.get(1) + " ");
				}
			}
		}
		int filterAndOrderExtraColumnExpsLength = filterAndOrderExtraColumnExps == null ? 0 : filterAndOrderExtraColumnExps.length;
		if (filterAndOrderExtraColumnExpsLength > 0) {
			for (int i = 0; i < filterAndOrderExtraColumnExpsLength; i++) {
				String filterAndOrderExtraColumnExp = filterAndOrderExtraColumnExps[i];
				if (filterAndOrderExtraColumnExp.indexOf(".") == -1) {
					boolean validColumnExpressions = validColumnExpression(clazz, filterAndOrderExtraColumnExp);
					if (!validColumnExpressions)
						throw new RuntimeException("Passed columnExpression is not valid. ColumnExpression [" + filterAndOrderExtraColumnExp + "] is not exists in Class [" + clazz.getName() + "]");
				} else {
					if (chainedColumnExpressionMap == null)
						chainedColumnExpressionMap = new HashMap();
					if (aliasesClassNameMap == null)
						aliasesClassNameMap = new HashMap();
					getPopulatedQueryStr(filterAndOrderExtraColumnExp, clazz, dataObjectID, chainedColumnExpressionMap, aliasesClassNameMap, associatedAliases, useNativeSql);
					List colJoinerDataList = (List) chainedColumnExpressionMap.get(filterAndOrderExtraColumnExp);
					joinStr += ((String) colJoinerDataList.get(1) + " ");
				}
			}
		}
		return new String[] { colExpressionStr, joinStr };
	}

	public String[] getFilterColumnParameters(String dataObjectId, String[] columnExpressions, boolean leftJoin) {
		String fullyQualifiedClassName = getFullyQualifiedClassName(dataObjectId);
		if (fullyQualifiedClassName == null) {
			throw new RuntimeException("Class not found with named [" + dataObjectId + "]");
		}
		int columnExpressionsLength = columnExpressions == null ? 0 : columnExpressions.length;
		Map chainedColumnExpressionMap = null;
		Map aliasesClassNameMap = null;
		Set associatedAliases = new HashSet();
		String[] filterColumnParameters = null;
		if (columnExpressionsLength > 0) {
			Class clazz = getDataObjectIdClass(fullyQualifiedClassName);
			boolean populateColumnExpression = false;
			for (int i = 0; i < columnExpressionsLength; i++) {
				String columnExpression = columnExpressions[i];
				if (columnExpression.indexOf(".") != -1) 
					populateColumnExpression = true;				
			}
			filterColumnParameters = new String[columnExpressionsLength];
			for (int i = 0; i < columnExpressionsLength; i++) {
				String columnExpression = columnExpressions[i];
				if (columnExpression.indexOf(".") == -1) {
					boolean validColumnExpressions = validColumnExpression(clazz, columnExpression);
					if (!validColumnExpressions) 
						throw new RuntimeException("Passed columnExpression is not valid. ColumnExpression [" + columnExpression + "] is not exists in Class [" + clazz.getName() + "]");
					
					if (columnExpression != null && columnExpression.trim().length() > 0) {
						if (populateColumnExpression) 
							filterColumnParameters[i] = (dataObjectId + "." + columnExpression);
						else 
							filterColumnParameters[i] = columnExpression;
						
					}
				} else {
					if (chainedColumnExpressionMap == null) 
						chainedColumnExpressionMap = new HashMap();
					
					if (aliasesClassNameMap == null) 
						aliasesClassNameMap = new HashMap();
					
					filterColumnParameters[i] = getPopulatedQueryStr(columnExpression, clazz, dataObjectId, chainedColumnExpressionMap, aliasesClassNameMap, associatedAliases, false);
				}
			}
		}
		return filterColumnParameters;
	}

	public String[] getFilterColumnParameters(String dataObjectId, String[] columnExpressions) {
		return getFilterColumnParameters(dataObjectId, columnExpressions, false);
	}

	private String getPopulatedQueryStr(String columnExpression, Class clazz, String parentAliasName, Map dataPopulatedMap, Map aliasesClassNameMap, Set associatedAliases, boolean useNativeSql) {
		AbstractEntityPersister entityPersister = getAbstractEntityPersister(clazz.getName());
		String[] columnExpressions = getColumnExpressions(columnExpression, ".");
		int columnExpressionsLength = columnExpressions == null ? 0 : columnExpressions.length;
		String comapringStr = columnExpression;
		String associatedJoin = "";
		String displayColumnExpression = null;
		String populatedColExpression = null;
		if (dataPopulatedMap.size() > 0) {
			while (comapringStr.indexOf(".") != -1) {
				comapringStr = comapringStr.substring(0, comapringStr.lastIndexOf("."));
				List dataPopulatedList = (List) dataPopulatedMap.get(comapringStr);
				if (dataPopulatedList != null) {
					populatedColExpression = comapringStr;
					parentAliasName = (String) dataPopulatedList.get(0);
					clazz = (Class) dataPopulatedList.get(2);
					entityPersister = getAbstractEntityPersister(clazz.getName());
					String colExpression = null;
					if (columnExpression.indexOf(".") != -1) {
						colExpression = columnExpression.substring(0, columnExpression.lastIndexOf("."));
						String tempColExpression = columnExpression.substring(columnExpression.lastIndexOf("."));
						colExpression = colExpression.contains(comapringStr) ? colExpression.substring(colExpression.indexOf(comapringStr) + comapringStr.length()) : colExpression;
						columnExpression = colExpression + tempColExpression;
					} else {
						colExpression = colExpression.contains(comapringStr) ? colExpression.substring(colExpression.indexOf(comapringStr) + comapringStr.length()) : colExpression;
					}
					columnExpression = columnExpression.substring(1);
					columnExpressions = getColumnExpressions(columnExpression, ".");
					columnExpressionsLength = columnExpressions == null ? 0 : columnExpressions.length;
					break;
				}
			}
		}
		String associatedClazzNameAlias = null;
		for (int i = 0; i < columnExpressionsLength; i++) {
			String colExpression = columnExpressions[i];
			List dataPopulatedList = new ArrayList();
			if (populatedColExpression == null)
				populatedColExpression = colExpression;
			else
				populatedColExpression = populatedColExpression + "." + colExpression;
			boolean validColumnExpressions = validColumnExpression(clazz, colExpression);
			if (!validColumnExpressions)
				throw new RuntimeException("Passed column is not valid. Passed columnExpression [" + colExpression + "] is not found in class [" + entityPersister.getEntityName() + "]");
			String[] propertyNames = entityPersister.getPropertyNames();
			int propertyNamesLength = propertyNames == null ? 0 : propertyNames.length;
			boolean colExpressionnPopulate = false;
			for (int j = 0; j < propertyNamesLength; j++) {
				String propertyName = propertyNames[j];
				if (propertyName.equals(colExpression)) {
					colExpressionnPopulate = true;
					Type propertyType = entityPersister.getPropertyType(colExpression);
					if (!isPrimitive(propertyType.getReturnedClass()) || !isDate(propertyType.getReturnedClass())) {
						String[] propertyColumnNames = entityPersister.getPropertyColumnNames(propertyName);
						if (propertyType instanceof CollectionType) {
							CollectionType collectionType = (CollectionType) propertyType;
							AbstractCollectionPersister collectionPersister = (AbstractCollectionPersister) ((SessionFactoryImpl) getSessionFactory()).getCollectionPersister(collectionType.getRole());
							entityPersister = (AbstractEntityPersister) collectionPersister.getElementPersister();
							String fullyQualifiedAssociatedClazzName = entityPersister.getEntityName();
							try {
								clazz = Class.forName(fullyQualifiedAssociatedClazzName);
							} catch (ClassNotFoundException e) {
								throw new RuntimeException("Class not found with named [" + fullyQualifiedAssociatedClazzName + "]");
							}
							String[] associatedClassNames = getColumnExpressions(fullyQualifiedAssociatedClazzName, ".");
							String associatedClazzName = associatedClassNames[associatedClassNames.length - 1];
							associatedClazzNameAlias = associatedClazzName;
							if (associatedAliases.contains(associatedClazzNameAlias))
								associatedClazzNameAlias = associatedClazzNameAlias + propertyName;
							if (useNativeSql) {
								String[] identifierColumnNames = entityPersister.getIdentifierColumnNames();
								if (identifierColumnNames != null && identifierColumnNames.length > 0) {
									String identifierColumnName = identifierColumnNames[0];
									if (propertyColumnNames != null && propertyColumnNames.length > 0) {
										String associatedPropertyColName = propertyColumnNames[0];
										associatedJoin = associatedJoin + (" left outer join " + associatedClazzName + " " + associatedClazzNameAlias + " on " + parentAliasName + "." + associatedPropertyColName + "=" + associatedClazzNameAlias + "." + identifierColumnName);
									}
								}
							} else
								associatedJoin = associatedJoin + (" left outer join " + parentAliasName + "." + propertyName + " " + associatedClazzNameAlias);
							parentAliasName = associatedClazzName;
							if (associatedAliases.contains(parentAliasName))
								parentAliasName = parentAliasName + propertyName;
						} else if (propertyType instanceof AssociationType) {
							clazz = propertyType.getReturnedClass();
							String associatedClassName = clazz.getName();
							entityPersister = getAbstractEntityPersister(associatedClassName);
							String[] associatedClassNames = getColumnExpressions(associatedClassName, ".");
							String associatedDataObjectId = associatedClassNames[associatedClassNames.length - 1];
							associatedClazzNameAlias = associatedDataObjectId;
							if (associatedAliases.contains(associatedClazzNameAlias))
								associatedClazzNameAlias = associatedClazzNameAlias + propertyName;
							if (useNativeSql) {
								String[] identifierColumnNames = entityPersister.getIdentifierColumnNames();
								if (identifierColumnNames != null && identifierColumnNames.length > 0) {
									String identifierColumnName = identifierColumnNames[0];
									if (propertyColumnNames != null && propertyColumnNames.length > 0) {
										String associatedPropertyColName = propertyColumnNames[0];
										associatedJoin = associatedJoin + (" left outer join " + associatedDataObjectId + " " + associatedClazzNameAlias + " on " + parentAliasName + "." + associatedPropertyColName + "=" + associatedClazzNameAlias + "." + identifierColumnName);
									}
								}
							} else
								associatedJoin = associatedJoin + (" left outer join " + parentAliasName + "." + propertyName + " " + associatedClazzNameAlias);
							parentAliasName = associatedDataObjectId;
							if (associatedAliases.contains(parentAliasName))
								parentAliasName = parentAliasName + propertyName;
						} else
							displayColumnExpression = parentAliasName + "." + colExpression;
						aliasesClassNameMap.put(associatedClazzNameAlias, clazz);
						associatedAliases.add(parentAliasName);
						dataPopulatedList.add(0, associatedClazzNameAlias);
						dataPopulatedList.add(1, associatedJoin);
						dataPopulatedList.add(2, clazz);
					}
					dataPopulatedMap.put(populatedColExpression, dataPopulatedList);
					break;
				}
			}
			if (!colExpressionnPopulate) {
				String identifierPropertyName = entityPersister.getIdentifierPropertyName();
				if (colExpression.equals(identifierPropertyName)) {
					aliasesClassNameMap.put(associatedClazzNameAlias, clazz);
					dataPopulatedList.add(0, associatedClazzNameAlias);
					dataPopulatedList.add(1, associatedJoin);
					dataPopulatedList.add(2, clazz);
					dataPopulatedMap.put(populatedColExpression, dataPopulatedList);
					displayColumnExpression = parentAliasName + "." + colExpression;
				}
			}
		}
		return displayColumnExpression;
	}

	private String[] getColumnExpressions(String columnExpression, String delimeter) {
		if (columnExpression != null && columnExpression.trim().length() > 0) {
			if (delimeter == null || delimeter.trim().length() == 0)
				delimeter = ".";
			StringTokenizer stringTokenizer = new StringTokenizer(columnExpression, delimeter);
			String[] columnExpressions = new String[stringTokenizer.countTokens()];
			int i = 0;
			while (stringTokenizer.hasMoreElements()) {
				columnExpressions[i] = (String) stringTokenizer.nextElement();
				i++;
			}
			return columnExpressions;
		}
		return null;
	}

	private Class getDataObjectIdClass(String fullyQualifiedClassName) {
		try {
			return Class.forName(fullyQualifiedClassName);
		} catch (ClassNotFoundException e) {
			throw new RuntimeException("Class not found with named [" + fullyQualifiedClassName + "]");
		}
	}

	private List getSearchingDataResult(String className, String[] columnExpressions, String filterStr, String orderBy, String joinStr, boolean fromServerSide, boolean allRecord) {

		if ((columnExpressions == null || columnExpressions.length == 0) && (filterStr == null || filterStr.trim().length() == 0) && (joinStr == null || joinStr.trim().length() == 0) && (className == null || className.trim().length() == 0)) {
			return null;
		} else {
			if (className.indexOf(".") != -1)
				className = className.substring((className.lastIndexOf(".") + 1));
			if (className == null || className.trim().length() == 0)
				throw new IllegalArgumentException("Passed table-name is invalid. Table name never be null or empty.");
			Session session = getSession();
			StringBuffer queryBuffer = new StringBuffer();
			try {
				queryBuffer.append("Select " + className + " from ").append(className).append(" ").append(className);

				if (joinStr != null && joinStr.trim().length() > 0)
					queryBuffer.append(joinStr);

				// ==============================================================================================
				int limitNumber = 0;
				boolean limitForShowResult = false;
				if (DB_MYSQL) {
					boolean remove_where = false;
					String filterWhere = "";
					String queryLimit = null;

					if (filterStr != null && filterStr.trim().length() > 0) {
						filterStr = filterStr.replaceAll(" and ", " AND ");
						filterStr = filterStr.replaceAll(" ROWNUM ", " rownum ");
						filterStr = filterStr.replaceAll("AND  rownum", "AND rownum");
						if (filterStr.lastIndexOf("AND rownum") != -1) {
							String limit = filterStr.substring(filterStr.indexOf("AND rownum") + 10, filterStr.length());
							if (limit.trim().startsWith("<"))
								limit = limit.trim().replaceFirst("<", " ");
							if (limit.trim().startsWith("="))
								limit = limit.trim().replaceFirst("=", " ");
							if (limit.trim().startsWith(">"))
								limit = limit.trim().replaceFirst(">", " ");
							if (limit.contains("AND")) {
								queryLimit = limit.substring(0, limit.indexOf("AND", 0));
								limitNumber = Integer.parseInt(queryLimit.trim()); // " LIMIT "+
								filterWhere = limit.substring(limit.indexOf("AND", 0), limit.length());// filterStr.substring(0,
							} else {
								limitNumber = Integer.parseInt(limit.trim());
								filterWhere = filterStr.substring(0, filterStr.lastIndexOf("AND rownum"));
							}
							filterStr = filterWhere;
							if (filterStr.startsWith("AND") || filterStr.startsWith(" AND")) {
								filterStr = "1=1 " + filterStr;
							}
						} else if (filterStr.lastIndexOf("rownum") != -1) {
							String limit = filterStr.substring(filterStr.indexOf("rownum") + 6, filterStr.length());
							limit = limit.replaceAll("=", " ");
							limit = limit.replaceAll("<", " ");
							limit = limit.replaceAll(">", " ");
							filterWhere = filterStr.substring(0, filterStr.lastIndexOf("rownum"));
							filterStr = filterWhere;
							remove_where = true;
						}
						if (remove_where)
							queryBuffer.append(filterStr);
						else
							queryBuffer.append(" WHERE ").append(filterStr);

					}

				}
				if (DB_ORACLE) {
					if (filterStr != null && filterStr.trim().length() > 0)
						queryBuffer.append(" WHERE ").append(filterStr);
				}
				if (orderBy != null && orderBy.trim().length() > 0)
					queryBuffer.append(" ORDER BY ").append(orderBy);

				if (limitNumber > 0) {
					limitForShowResult = true;
				}

				Query query = session.createQuery(queryBuffer.toString());
				if (!allRecord) {
					query.setFirstResult(0);
					query.setMaxResults(100);
				}
				List dataValuesList = query.list();
				if (fromServerSide)
					return dataValuesList;
				else
					return getColumnDataList(dataValuesList, columnExpressions);
			} catch (Exception ex) {
				ex.printStackTrace();
				throw new RuntimeException("Exception while executing query [" + queryBuffer.toString() + "]" + ex);
			} finally {
				if (session.isConnected() && !fromServerSide)
					session.close();
				else if (fromServerSide)
					openSession = session;
			}
		}
	}

	private List getColumnDataList(List objectList, String[] columnExpressions) {

		if ((objectList == null) || (objectList.size() == 0))
			return null;

		return DataObjectPopulation.populateDataObjects(objectList, columnExpressions);
	}

	private List getSearchingDataResult(String className, String columnExpressionStr, String filterStr, String joinStr, String orderBy, boolean fetchHierarcalData, boolean fromServerSide, boolean allRecord) {
		if ((columnExpressionStr == null || columnExpressionStr.trim().length() == 0) && (filterStr == null || filterStr.trim().length() == 0) && (joinStr == null || joinStr.trim().length() == 0) && (orderBy == null || orderBy.trim().length() == 0) && (className == null || className.trim().length() == 0))
			return null;
		if (className.indexOf(".") != -1)
			className = className.substring((className.lastIndexOf(".") + 1));
		if (className == null || className.trim().length() == 0)
			throw new IllegalArgumentException("Passed table-name is invalid. Table name never be null or empty.");
		Session session = getSession();
		StringBuffer queryBuffer = new StringBuffer();

		try {

			if (columnExpressionStr != null && columnExpressionStr.trim().length() > 0)
				queryBuffer.append("Select distinct ").append(columnExpressionStr);
			queryBuffer.append(" from ").append(className).append(" ").append(className);

			if (joinStr != null && joinStr.trim().length() > 0)
				queryBuffer.append(joinStr);
			int limitNumber = 0;
			boolean limitForShowResult = false;
			if (DB_MYSQL) {
				boolean remove_where = false;
				String filterWhere = "";

				String queryLimit = null;

				if (filterStr != null && filterStr.trim().length() > 0) {
					System.err.println("wherteeeeeeee-------->" + filterStr);
					filterStr = filterStr.replaceAll(" and ", " AND ");
					filterStr = filterStr.replaceAll(" ROWNUM ", " rownum ");
					filterStr = filterStr.replaceAll("AND  rownum", "AND rownum");

					if (filterStr.lastIndexOf("AND rownum") != -1) {
						String limit = filterStr.substring(filterStr.indexOf("AND rownum") + 10, filterStr.length());
						System.err.println("limit-----1---->" + limit);
						if (limit.trim().startsWith("<"))
							limit = limit.trim().replaceFirst("<", " ");
						if (limit.trim().startsWith("="))
							limit = limit.trim().replaceFirst("=", " ");
						// http://stackoverflow.com/questions/2089128/save-blob-to-db-using-hibernate
						if (limit.trim().startsWith(">"))
							limit = limit.trim().replaceFirst(">", " ");
						System.err.println("limit------44--->" + limit);
						if (limit.contains("AND")) {
							queryLimit = limit.substring(0, limit.indexOf("AND", 0));
							System.err.println("queryLimit-------->" + queryLimit);
							limitNumber = Integer.parseInt(queryLimit.trim()); // " LIMIT "+
							filterWhere = limit.substring(limit.indexOf("AND", 0), limit.length());// filterStr.substring(0,
						} else {
							limitNumber = Integer.parseInt(limit.trim());
							filterWhere = filterStr.substring(0, filterStr.lastIndexOf("AND rownum"));
						}
						filterStr = filterWhere;
						if (filterStr.startsWith("AND") || filterStr.startsWith(" AND")) {
							filterStr = "1=1 " + filterStr;
						}
						System.err.println("wherteeeeeeee----after remove rownum---->" + filterStr);
					} else if (filterStr.lastIndexOf("rownum") != -1) {
						String limit = filterStr.substring(filterStr.indexOf("rownum") + 6, filterStr.length());
						System.err.println("limit-----1--else-->" + limit);
						limit = limit.replaceAll("=", " ");
						limit = limit.replaceAll("<", " ");
						limit = limit.replaceAll(">", " ");
						System.err.println("limit------4--else->" + limit);
						// queryLimit = Integer.parseInt(limit.trim()); //
						// " limit "+limit.trim()+" ";
						System.err.println("queryLimit-------else->" + queryLimit);
						filterWhere = filterStr.substring(0, filterStr.lastIndexOf("rownum"));
						filterStr = filterWhere;
						System.err.println("wherteeeeeeee----after remove rownum---elseeeeeeee->" + filterStr);
						remove_where = true;
					}
					if (remove_where)
						queryBuffer.append(filterStr);
					else
						queryBuffer.append(" WHERE ").append(filterStr);

				}

			}
			if (DB_ORACLE) {
				if (filterStr != null && filterStr.trim().length() > 0)
					queryBuffer.append(" WHERE ").append(filterStr);
			}
			System.err.println("wherteeeeeeee----now->" + filterStr);
			if (orderBy != null && orderBy.trim().length() > 0)
				queryBuffer.append(" ORDER BY ").append(orderBy);

			if (limitNumber > 0) 
				limitForShowResult = true;
			
			System.err.println("queryBuffer----now--->" + queryBuffer);
			Query query = null;
			if (fetchHierarcalData) {
				System.err.println("---------------SQL QUERY EXCUTEDDDDDDDDDDDDDDDDDD-------------------------------");
				query = session.createSQLQuery(queryBuffer.toString());
			} else 
				query = session.createQuery(queryBuffer.toString());
			
			
			if(!allRecord){
				query.setFirstResult(0);
				query.setMaxResults(100);
			}
			List dataValuesList = query.list();
			System.out.println("yyyyyyyyyy--------------query----------->>>>" + query);
			int size = (dataValuesList == null ? 0 : dataValuesList.size());

			return getColumnDataList(dataValuesList, fetchHierarcalData);
		} catch (Exception ex) {
			ex.printStackTrace();
			throw new RuntimeException("Exception while executing query [" + queryBuffer.toString() + "]" + ex);
		} finally {
			if (session.isConnected() && !fromServerSide)
				session.close();
			else if (fromServerSide)
				openSession = session;
		}
	}

	private List getColumnDataList(List dataValuesList, boolean isNativeSql) {
		if (dataValuesList == null)
			return null;
		int dataValuesListSize = dataValuesList.size();
		List dataList = new ArrayList(dataValuesListSize);
		for (int i = 0; i < dataValuesListSize; i++) {
			Object dataObject = dataValuesList.get(i);
			if (dataObject instanceof Object[]) {
				Object[] objs = ((Object[]) dataObject);
				int length = (objs == null ? 0 : objs.length);
				List columnExpDataValueList = new ArrayList(length);
				for (int j = 0; j < length; j++) {
					Object dataValueObj = objs[j];
					if (isNativeSql) {
						if (dataValueObj instanceof BigDecimal)
							columnExpDataValueList.add(Long.valueOf(((BigDecimal) dataValueObj).longValue()));
						else
							columnExpDataValueList.add(dataValueObj);
					} else
						columnExpDataValueList.add(dataValueObj);
				}
				dataList.add(columnExpDataValueList);
			} else
				dataList.add(dataObject);
		}
		return dataList;
	}

	public Session getSession() {
		SessionFactory sessionFactory = getSessionFactory();
		return sessionFactory.openSession();
	}

	private SessionFactory getSessionFactory() {
		if (partySessionFactoryName == null) {
			if (WEB_MODE) {
				try {
					InitialContext ctx = new InitialContext();
					partySessionFactoryName = (SessionFactory) ctx.lookup("java:/hibernate/MetaDataSessionFactory");
				} catch (NamingException e) {
					throw new RuntimeException(e);
				}
			} else
				partySessionFactoryName = com.pbd.connection.HibernateUtil.sessionFactory;
		}
		return partySessionFactoryName;
	}

	private boolean validColumnExpression(Class clazz, String columnExpression) {
		Field[] fields = clazz.getDeclaredFields();

		int length = (fields == null ? 0 : fields.length);
		for (int i = 0; i < length; i++) {
			Field field = fields[i];
			if (field.getName().equals(columnExpression))
				return true;
		}
		return false;
	}

	public DataClass populateDataClass(String dataObjectId, String[] columnExpressions) {
		classesMap = new HashMap();
		String fullyQualifiedClassName = getFullyQualifiedClassName(dataObjectId);
		EntityPersister entityPersister = getAbstractEntityPersister(fullyQualifiedClassName);
		if (entityPersister instanceof AbstractEntityPersister) {

			AbstractEntityPersister abstractEntityPersister = (AbstractEntityPersister) entityPersister;
			DataClass dataClass = new DataClass();
			dataClass.setClassName(abstractEntityPersister.getEntityName());
			dataClass.setTableName(abstractEntityPersister.getTableName());
			dataClass.setMutable(abstractEntityPersister.isMutable());

			dataClass.setDataColumns(getDataFields(abstractEntityPersister, columnExpressions));
			return dataClass;
		}
		return null;
	}

	private DataColumn[] getDataFields(AbstractEntityPersister abstractEntityPersister, String[] columnExpressions) {
		int columnExpressionLength = columnExpressions == null ? 0 : columnExpressions.length;
		if (columnExpressionLength > 0) {
			return populateDataColumns(abstractEntityPersister, columnExpressions);
		}
		return populateDataColumns(abstractEntityPersister);
	}

	private DataColumn[] populateDataColumns(AbstractEntityPersister abstractEntityPersister) {
		String[] propertyNames = abstractEntityPersister.getPropertyNames();
		int propertyLength = propertyNames == null ? 0 : propertyNames.length;
		DataColumn[] dataColumns = new DataColumn[propertyLength + 1];
		for (int i = 0; i < propertyLength; i++) {
			String propertyName = propertyNames[i];
			Type type = abstractEntityPersister.getPropertyType(propertyName);
			if (type instanceof CollectionType)
				continue;
			DataColumn dataColumn = null;
			String dataType = type.getReturnedClass().getName();
			if (type instanceof AssociationType) {

				String referenceDataObjectId = dataType.indexOf(".") != -1 ? dataType.substring(dataType.lastIndexOf(".") + 1) : dataType;
				if (classesMap.containsKey(referenceDataObjectId)) {
					return (DataColumn[]) classesMap.get(referenceDataObjectId);
				}
				dataColumn = new ReferenceDataColumn();
				AbstractEntityPersister referenceEntityPersister = getAbstractEntityPersister(dataType);
				String identifierPropertyName = referenceEntityPersister.getIdentifierPropertyName();
				((ReferenceDataColumn) dataColumn).setReferenceKeyColumnExpression(identifierPropertyName);
				((ReferenceDataColumn) dataColumn).setReferenceDataObjectId(referenceDataObjectId);
				String[] referenceDisplayColumnExpression = getReferenceDisplayColumnExpression(referenceEntityPersister.getPropertyNames(), referenceEntityPersister.getPropertyTypes(), referenceDataObjectId, identifierPropertyName);
				((ReferenceDataColumn) dataColumn).setReferenceDisplayColumnExpression(referenceDisplayColumnExpression[0]);
				((ReferenceDataColumn) dataColumn).setReferenceDisplayColExpDataType(referenceDisplayColumnExpression[1]);
				DataColumn[] referenceDataColumns = getDataFields(referenceEntityPersister, null);
				((ReferenceDataColumn) dataColumn).setReferenceDataColumns(referenceDataColumns);
				classesMap.put(referenceDataObjectId, referenceDataColumns);
			} else
				dataColumn = getDataColumn(abstractEntityPersister, propertyName, null);
			dataColumns[i] = dataColumn;
		}
		DataColumn dataColumn = new DataColumn();
		dataColumn.setDataType(abstractEntityPersister.getIdentifierType().getReturnedClass().getName());
		String columnName = abstractEntityPersister.getIdentifierColumnNames()[0];
		if (columnName.indexOf("\"") != -1)
			columnName = columnName.substring(columnName.indexOf("\"") + 1, columnName.lastIndexOf("\""));
		dataColumn.setColumnName(columnName);
		String identifierPropertyName = abstractEntityPersister.getIdentifierPropertyName();
		dataColumn.setFieldName(identifierPropertyName);
		dataColumns[dataColumns.length - 2] = dataColumn;
		return dataColumns;
	}

	private DataColumn[] populateDataColumns(AbstractEntityPersister abstractEntityPersister, String[] columnExpressions) {
		int columnExpressionsLength = columnExpressions.length;
		String[] propertyNames = abstractEntityPersister.getPropertyNames();
		DataColumn[] dataColumns = new DataColumn[columnExpressionsLength];
		List columnList = new ArrayList();
		for (int i = 0; i < columnExpressionsLength; i++) {
			String columnExpression = columnExpressions[i];
			if (columnExpression.indexOf(".") != -1) {
				populatedAssociatedFields(dataColumns, columnExpression, abstractEntityPersister, i, columnList);
			} else {
				DataColumn dataColumn = null;
				if (isProcessableColExpression(columnExpression, propertyNames)) {
					dataColumn = getDataColumn(abstractEntityPersister, columnExpression, null);
				} else {
					String identifierPropertyName = abstractEntityPersister.getIdentifierPropertyName();
					if (isProcessableProperty(identifierPropertyName, columnExpressions)) {
						dataColumn = new DataColumn();
						dataColumn.setDataType(abstractEntityPersister.getIdentifierType().getReturnedClass().getName());
						String columnName = abstractEntityPersister.getIdentifierColumnNames()[0];
						if (columnName.indexOf("\"") != -1)
							columnName = columnName.substring(columnName.indexOf("\"") + 1, columnName.lastIndexOf("\""));
						dataColumn.setColumnName(columnName);
						dataColumn.setFieldName(identifierPropertyName);
					}
				}
				dataColumns[i] = dataColumn;
			}
		}
		return dataColumns;
	}

	private boolean isProcessableColExpression(String columnExpression, String[] propertyNames) {
		int propertiesLength = propertyNames == null ? 0 : propertyNames.length;
		for (int i = 0; i < propertiesLength; i++) {
			if (propertyNames[i].equals(columnExpression)) 
				return true;
			
		}
		return false;
	}

	private DataColumn getDataColumn(AbstractEntityPersister abstractEntityPersister, String columnExpression, String displayCoulmnExpression) {
		String[] propertyNames = abstractEntityPersister.getPropertyNames();
		int propertyNamesLength = propertyNames == null ? 0 : propertyNames.length;
		for (int i = 0; i < propertyNamesLength; i++) {
			String propertyName = propertyNames[i];
			if (propertyName.equals(columnExpression)) {
				Type propertyType = abstractEntityPersister.getPropertyType(propertyName);
				String dataType = propertyType.getReturnedClass().getName();
				DataColumn dataColumn = new DataColumn();
				dataColumn.setDataType(dataType);
				String[] propertyColumnNames = abstractEntityPersister.getPropertyColumnNames(propertyName);
				String columnName = propertyColumnNames[0];
				if (columnName != null && columnName.indexOf("\"") != -1) {
					columnName = columnName.substring(columnName.indexOf("\"") + 1, columnName.lastIndexOf("\""));
				}
				if (columnName == null) {
					columnName = propertyName;
				}
				dataColumn.setColumnName(columnName);
				if (displayCoulmnExpression != null)
					dataColumn.setFieldName(displayCoulmnExpression);
				else
					dataColumn.setFieldName(propertyName);
				boolean[] nullAbility = abstractEntityPersister.getPropertyNullability();
				boolean nullAllowed = nullAbility[i];
				dataColumn.setNullAllowed(nullAllowed);
				boolean[] updateAbility = abstractEntityPersister.getPropertyUpdateability();
				boolean[] insertAbility = abstractEntityPersister.getPropertyInsertability();
				boolean updateAllowed = updateAbility[i];
				dataColumn.setUpdate(updateAllowed);
				boolean insertAllowed = insertAbility[i];
				dataColumn.setInsert(insertAllowed);
				return dataColumn;
			}
		}
		String identifierPropertyName = abstractEntityPersister.getIdentifierPropertyName();
		if (identifierPropertyName.equals(columnExpression)) {
			Type propertyType = abstractEntityPersister.getIdentifierType();
			String dataType = propertyType.getReturnedClass().getName();
			DataColumn dataColumn = new DataColumn();
			dataColumn.setDataType(dataType);
			String[] propertyColumnNames = abstractEntityPersister.getIdentifierColumnNames();
			String columnName = propertyColumnNames[0];
			if (columnName.indexOf("\"") != -1)
				columnName = columnName.substring(columnName.indexOf("\"") + 1, columnName.lastIndexOf("\""));
			dataColumn.setColumnName(columnName);
			dataColumn.setFieldName(identifierPropertyName);
			return dataColumn;
		}
		return null;
	}

	private void populatedAssociatedFields(DataColumn[] dataColumns, String columnExpression, AbstractEntityPersister abstractEntityPersister, int index, List columnList) {
		String associatedColumnEXpression = columnExpression;
		AbstractEntityPersister tempAbstractEntityPersister = abstractEntityPersister;
		while (columnExpression.indexOf(".") != -1) {
			String colExpression = columnExpression.substring(0, columnExpression.indexOf(".")).trim();
			Type propertyType = tempAbstractEntityPersister.getPropertyType(colExpression);
			if (propertyType == null) {
				throw new RuntimeException("Passed columnExpression [" + associatedColumnEXpression + "] is wrong.");
			}
			if (propertyType instanceof CollectionType) {
				CollectionType collectionType = (CollectionType) propertyType;
				AbstractCollectionPersister collectionPersister = (AbstractCollectionPersister) ((SessionFactoryImpl) getSessionFactory()).getCollectionPersister(collectionType.getRole());
				tempAbstractEntityPersister = (AbstractEntityPersister) collectionPersister.getElementPersister();
			} else if (propertyType instanceof AssociationType) {
				Class associatedClazz = propertyType.getReturnedClass();
				String associatedClassName = associatedClazz.getName();
				tempAbstractEntityPersister = getAbstractEntityPersister(associatedClassName);
			}
			columnExpression = columnExpression.substring(columnExpression.indexOf(".") + 1, columnExpression.length());
		}
		if (columnList.contains(columnExpression)) {
			associatedColumnEXpression = populatedColumnString(associatedColumnEXpression);
			columnList.add(associatedColumnEXpression);
			dataColumns[index] = getDataColumn(tempAbstractEntityPersister, columnExpression, associatedColumnEXpression);
		} else {
			columnList.add(columnExpression);
			dataColumns[index] = getDataColumn(tempAbstractEntityPersister, columnExpression, null);
		}

	}

	private String populatedColumnString(String associatedColumnEXpression) {
		String populatedColumnStr = "";
		while (associatedColumnEXpression.indexOf(".") != -1) {
			String colExpression = associatedColumnEXpression.substring(0, associatedColumnEXpression.indexOf(".")).trim();
			associatedColumnEXpression = associatedColumnEXpression.substring(associatedColumnEXpression.indexOf(".") + 1, associatedColumnEXpression.length());
			populatedColumnStr += colExpression;
		}
		populatedColumnStr += associatedColumnEXpression;
		return populatedColumnStr;
	}

	private boolean isProcessableProperty(String propertyName, String[] columnExpressions) {
		int length = columnExpressions == null ? 0 : columnExpressions.length;
		if (length > 0) {
			for (int i = 0; i < length; i++) {
				String colExpression = columnExpressions[i];
				if (colExpression != null && colExpression.trim().length() > 0) {
					if (colExpression.equals(propertyName)) {
						return true;
					}
				}
			}
			return false;
		}
		return true;
	}

	private String[] getReferenceDisplayColumnExpression(String[] propertyNames, Type[] referencePropertyTypes, String dataObjectId, String keyColumnExpression) {
		String referenceDisplayColumnExpression = dataObjectId + "name";
		int length = propertyNames == null ? 0 : propertyNames.length;
		String keyPropertyType = null;
		for (int i = 0; i < length; i++) {
			String propertyName = propertyNames[i];
			if (propertyName.equalsIgnoreCase(referenceDisplayColumnExpression)) {
				String propType = getPropertyType(referencePropertyTypes, i);
				return new String[] { propertyName, propType };
			} else if (propertyName.equalsIgnoreCase(keyColumnExpression)) {
				keyPropertyType = getPropertyType(referencePropertyTypes, i);
			}
		}
		return new String[] { keyColumnExpression, keyPropertyType };
	}

	private String getPropertyType(Type[] referencePropertyTypes, int i) {
		Type propertyType = referencePropertyTypes[i];
		return propertyType.getReturnedClass().getName();
	}

	private static boolean isPrimitive(Class objectClass) {
		if (objectClass.isPrimitive() || objectClass == Boolean.class || objectClass == Character.class || objectClass == Byte.class || objectClass == Short.class || objectClass == Integer.class || objectClass == Long.class || objectClass == Float.class || objectClass == Double.class || objectClass == String.class || objectClass == Void.class)
			return true;
		else
			return false;
	}

	private static boolean isDate(Class objectClass) {
		if (objectClass == Date.class)
			return true;
		Class clas = objectClass;

		do {
			if (clas == Date.class) {
				return true;
			}
			clas = clas.getSuperclass();
		} while (clas != null);

		return false;
	}

	public List dataList(String queryStr, boolean isSQL) {
		Session session = getSession();
		Transaction transaction = session.beginTransaction();
		if (!session.isOpen()) {
			System.out.println("session is not open");
		}
		if (!transaction.isActive()) {
			System.out.println("Transaction is Active");
		}
		List list = null;
		try {
			Query query = null;
			if (isSQL) {
				query = session.createSQLQuery(queryStr);
			} else {
				query = session.createQuery(queryStr);
			}
			list = query.list();
			transaction.commit();
			return list;
		} catch (Exception ex) {
			transaction.rollback();
			throw new RuntimeException(ex);
		} finally {
			if (session.isOpen())
				session.close();
			return list;
		}
	}

	public List getCommission(String dataObjectId, String filterStr, String orderBy) {
		return null;
	}

	public void closeSession() {
		if (openSession != null && openSession.isOpen()) {
			openSession.close();
		}
	}

	public List getTableValues(List modelList, List tableNameList, String stripeOrgID) {
		List list = new ArrayList();
		if (modelList != null && modelList.size() > 0)
			list.add(getTableMap(modelList, stripeOrgID, "ModelMaster"));
		else
			list.add(null);

		if (tableNameList != null && tableNameList.size() > 0)
			list.add(getTableMap(tableNameList, stripeOrgID, "VehicleMasterTable"));
		else
			list.add(null);
		return list;
	}

	private Map getTableMap(List tableNameList, String stripeOrgID, String tableName) {
		Map map = new HashMap();
		int size = tableNameList == null ? 0 : tableNameList.size();
		String fullyQualifiedClassName = getFullyQualifiedClassName(tableName);
		if (fullyQualifiedClassName == null)
			throw new IllegalArgumentException("Passed data is invalid. BDO class is not exists corresponnding to [" + "VEHICLEMASTERTABLE" + "]");

		if (fullyQualifiedClassName.indexOf(".") != -1)
			fullyQualifiedClassName = fullyQualifiedClassName.substring((fullyQualifiedClassName.lastIndexOf(".") + 1));
		for (int i = 0; i < size; i++) {
			String tableName1 = (String) tableNameList.get(i);
			if (tableName1 != null && tableName1.trim().length() > 0) {
				Query query = null;
				if (tableName.equalsIgnoreCase("VehicleMasterTable")) {
					if (stripeOrgID != null && stripeOrgID.trim().length() > 0)
						query = getSession().createQuery("select " + fullyQualifiedClassName + " from " + fullyQualifiedClassName + " " + fullyQualifiedClassName + " WHERE MASTERTYPE= '" + tableName1 + "' AND stripeByOrgID=" + stripeOrgID);
					else
						query = getSession().createQuery("select " + fullyQualifiedClassName + " from " + fullyQualifiedClassName + " " + fullyQualifiedClassName + " WHERE MASTERTYPE= '" + tableName1 + "'");
				} else if (tableName.equalsIgnoreCase("ModelMaster")) {
					if (stripeOrgID != null && stripeOrgID.trim().length() > 0)
						query = getSession().createQuery("select " + fullyQualifiedClassName + " from " + fullyQualifiedClassName + " " + fullyQualifiedClassName + " WHERE modelType= '" + tableName1 + "' AND stripeByOrgID=" + stripeOrgID);
					else
						query = getSession().createQuery("select " + fullyQualifiedClassName + " from " + fullyQualifiedClassName + " " + fullyQualifiedClassName + " WHERE modelType= '" + tableName1 + "'");
				}
				List list = query.list();
				int listSize = list == null ? 0 : list.size();
				List outerList = new ArrayList();
				
				map.put(tableName1, outerList);
			}
		}
		if (size == 0)
			return null;
		return map;
	}

	public List getSearchResult(String strQuery) {
		List targetList = new ArrayList();
		try {

			Session session = getSession();
			Transaction transaction = session.beginTransaction();
			Statistics stats = getSessionFactory().getStatistics();
			stats.setStatisticsEnabled(true);
			Query query = session.createSQLQuery(strQuery);
			List list = query.list();
			transaction.commit();
			int size = (list == null ? 0 : list.size());

			for (Iterator iterator = list.iterator(); iterator.hasNext();) {
				Object object = iterator.next();
				if (object != null) {
					if (object instanceof Object[]) {
						Object[] col = (Object[]) object;
						if (col != null) {
							List innerlist = new ArrayList();
							// Object[] columnExpress = new Object[col.length];
							for (int index = 0; index < col.length; index++) {
								Object obj = col[index];

								if (obj != null) {
									//System.err.println(obj.getClass());
									if (obj instanceof BigDecimal) {
										BigDecimal bigDecimal = (BigDecimal) obj;
										innerlist.add(Long.valueOf(bigDecimal.toString()));
									}
									else if (obj instanceof BigInteger) {
										BigInteger bigInteger = (BigInteger) obj;
										innerlist.add(Integer.valueOf(bigInteger.toString()));
									} else if (obj instanceof Double)
										innerlist.add((Double) obj);
									else if (obj instanceof String)
										innerlist.add((String) obj);
									else if (obj instanceof Character)
										innerlist.add((Character) obj);
									else if (obj instanceof Boolean)
										innerlist.add((Boolean) obj);
									else if (obj instanceof java.sql.Timestamp){
										java.sql.Timestamp st = (java.sql.Timestamp) obj;
										innerlist.add(new Date(st.getTime()));
									}else if (obj instanceof java.sql.Date){
										java.sql.Date date =(java.sql.Date) obj;
										innerlist.add(new Date(date.getTime()));
									}
								} else
									innerlist.add(null);
							}
							//System.err.println("innerlist :: size:"+innerlist.size());
							targetList.add(innerlist);
						}
					} else if (object instanceof BigDecimal) {
						BigDecimal bigDecimal = (BigDecimal) object;
						targetList.add(Long.valueOf(bigDecimal.toString()));
					} else if (object instanceof BigInteger) {
						BigInteger bigInteger = (BigInteger) object;
						targetList.add(Long.valueOf(bigInteger.toString()));
					} else if (object instanceof String)
						targetList.add((String) object);
					else if (object instanceof Character)
						targetList.add((Character) object);
					else if (object instanceof java.sql.Timestamp){
						java.sql.Timestamp st = (java.sql.Timestamp) object;
						targetList.add(new Date(st.getTime()));
					}else if (object instanceof Double)
						targetList.add((Double) object);
					else if (object instanceof Boolean)
						targetList.add((Boolean) object);
					else if (object instanceof java.sql.Date){
						java.sql.Date date =(java.sql.Date) object;
						targetList.add(new Date(date.getTime()));
					}

				}
			}

		} catch (Exception exception) {
			exception.printStackTrace();
		}
		return targetList;
	}

	public void updateGrievanceCategorySetup(String updateQuery) {
		Session session = getSession();
		Transaction transaction = session.beginTransaction();
		Statistics stats = getSessionFactory().getStatistics();
		stats.setStatisticsEnabled(true);
		Query query = session.createQuery(updateQuery);
		int rowCount = query.executeUpdate();
		transaction.commit();

	}

	public void updateClaimObject(String updateQuery) {
		Session session = getSession();
		try {
			Statistics stats = getSessionFactory().getStatistics();
			stats.setStatisticsEnabled(true);
			Query query = session.createQuery(updateQuery);
			int rowCount = query.executeUpdate();
			System.out.println("rowCount" + rowCount);
			session.connection().commit();
		} catch (HibernateException e) {
			e.printStackTrace();
			try {
				session.connection().rollback();
			} catch (HibernateException e1) {
				e1.printStackTrace();
			} catch (SQLException e1) {
				e1.printStackTrace();
			}

		} catch (SQLException e) {
			e.printStackTrace();
			try {
				session.connection().rollback();
			} catch (HibernateException e1) {
				e1.printStackTrace();
			} catch (SQLException e1) {
				e1.printStackTrace();
			}
		}

	}

	public Date getServerDate() {
		return new Date();
	}

	public String filterQueryRemoveLimit(String filterStr) {
		String filterWhere = "";
		String queryLimit = "";
		if (filterStr != null && filterStr.trim().length() > 0) {
			if (filterStr.lastIndexOf("AND rownum") != -1) {
				String limit = filterStr.substring(filterStr.indexOf("AND rownum") + 10, filterStr.length());
				limit = limit.replaceAll("=", " ");
				limit = limit.replaceAll("<", " ");
				limit = limit.replaceAll(">", " ");
				queryLimit = "  limit " + limit;
				filterWhere = filterStr.substring(0, filterStr.lastIndexOf("AND rownum"));
				filterStr = filterWhere;
			}
		}
		return "";
	}

}